package org.jasig.cas.ext.pac4j.web.flow;

import org.apache.commons.lang3.StringUtils;
import org.jasig.cas.authentication.handler.PasswordEncoder;
import org.jasig.cas.ext.pac4j.plugin.common.ClientType;
import org.jasig.cas.ext.vo.UserBindVo;
import org.jasig.cas.support.pac4j.authentication.principal.ClientCredential;
import org.pac4j.core.client.Client;
import org.pac4j.core.profile.UserProfile;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.core.PreparedStatementSetter;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
import org.springframework.transaction.TransactionStatus;
import org.springframework.transaction.support.TransactionCallback;
import org.springframework.transaction.support.TransactionTemplate;

import javax.servlet.http.HttpServletRequest;
import javax.validation.constraints.NotNull;
import java.sql.*;

/**
 * Created by rain.wen on 2016/9/3.
 */
public class OAuthBindJdbcAction extends OAuthBindAction {

    @NotNull
    private DataSourceTransactionManager transactionManager;

    @NotNull
    private PasswordEncoder passwordEncoder;

    /**
     * JdbcTemplate
     */
    @NotNull
    protected JdbcTemplate jdbcTemplate;

    public void setJdbcTemplate(JdbcTemplate jdbcTemplate) {
        this.jdbcTemplate = jdbcTemplate;
    }

    public JdbcTemplate getJdbcTemplate() {
        return jdbcTemplate;
    }

    public DataSourceTransactionManager getTransactionManager() {
        return transactionManager;
    }

    public void setTransactionManager(DataSourceTransactionManager transactionManager) {
        this.transactionManager = transactionManager;
    }

    public PasswordEncoder getPasswordEncoder() {
        return passwordEncoder;
    }

    public void setPasswordEncoder(PasswordEncoder passwordEncoder) {
        this.passwordEncoder = passwordEncoder;
    }

    @Override
    protected boolean bind(final HttpServletRequest request, final Client client,
                           final ClientCredential credentials) {
        if (credentials == null) {
            return false;
        }

        final UserProfile profile = credentials.getUserProfile();
        if (profile == null) {
            return false;
        }
        final UserBindVo userBindVo = userProfileToUserBindVo(client, profile);
        TransactionTemplate transactionTemplate = new TransactionTemplate(getTransactionManager());
        return transactionTemplate.execute(new TransactionCallback<Boolean>() {
            @Override
            public Boolean doInTransaction(TransactionStatus status) {
                if (profile == null) {
                    return false;
                }
                String bindSql = "insert into t_user_bind" +
                        "(user_id,nick_name,head_img_url,login_type,open_id,create_time,update_time) " +
                        "values(?,?,?,?,?,?,?)";
                jdbcTemplate.update(bindSql,
                        new PreparedStatementSetter() {
                            @Override
                            public void setValues(PreparedStatement ps) throws SQLException {
                                ps.setString(1, userBindVo.getUserId());
                                ps.setString(2, userBindVo.getNickName());
                                ps.setString(3, userBindVo.getHeadImgUrl());
                                ps.setString(4, userBindVo.getLoginType());
                                ps.setString(5, userBindVo.getOpenId());
                                ps.setTimestamp(6, new Timestamp(System.currentTimeMillis()));
                                ps.setTimestamp(7, new Timestamp(System.currentTimeMillis()));
                            }
                        });
                //入库操作
                logger.info("==> bind user info loginType={}, openId={}", userBindVo.getLoginType(), userBindVo.getOpenId());
                return true;
            }
        });
    }

    private UserBindVo userProfileToUserBindVo(Client client, UserProfile profile) {
        UserBindVo userBindVo = new UserBindVo();
        String loginType = client.getName().replace("Client", "").toUpperCase();
        userBindVo.setUserId("");
        userBindVo.setOpenId(profile.getId());
        userBindVo.setLoginType(loginType);
        userBindVo.setHeadImgUrl(profile.getAttribute("picture_url") + ""); //头像
        userBindVo.setNickName(profile.getAttribute("username") + ""); //昵称
        return userBindVo;
    }
}
